﻿using System;
using System.Collections.Generic;
using SlamCms.Collections;

namespace SlamCms.Caching
{
	public class DefaultCacheManager : ICacheManager
	{
		private static SafeDictionary<string, CacheEntry> cache = new SafeDictionary<string, CacheEntry>();

		public bool Contains(string key, bool allowDirty = true)
		{
			CacheEntry cacheEntry;
			if (cache.TryGetValue(key, out cacheEntry))
			{
				if (!allowDirty && cacheEntry.IsDirty)
					return false;

				return true;
			}

			return false;
		}

		public T Get<T>(string key, bool allowDirty = true) where T : class
		{
			T value = null;
			CacheEntry cacheEntry;
			if (cache.TryGetValue(key, out cacheEntry))
			{
				if (allowDirty || !cacheEntry.IsDirty)
					value = cacheEntry.Value as T;

				cacheEntry.LastAccessed = DateTime.Now;
			}

			return value;
		}

		public void Save<T>(string key, T instance, TimeSpan? timeout = null, bool sliding = false) where T : class
		{
			cache[key] = CacheEntry.Create(key, instance);
		}

		public void Remove(string key)
		{
			CacheEntry cacheEntry;
			if (cache.TryGetValue(key, out cacheEntry))
			{
				cacheEntry.IsDirty = true;	
			}
		}

		public IEnumerable<string> Keys
		{
			get { return cache.Keys; }
		}

		private class CacheEntry
		{
			public static CacheEntry Create(string key, object value)
			{
				return new CacheEntry()
				{
					DateCreated = DateTime.Now,
					LastAccessed = DateTime.Now,
					IsDirty = false,
					Key = key,
					Value = value
				};
			}

			public DateTime DateCreated { get; set; }
			public DateTime LastAccessed { get; set; }
			public bool IsDirty { get; set; }
			public string Key { get; set; }
			public object Value { get; set; }
		}
	}
}